using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Perovich.GameObjects.Helpers;
using Microsoft.Xna.Framework.Input.Touch;

namespace Perovich.GameObjects.Controls
{

    /// <summary>
    /// The <see cref="ClickableControl"/> is an abstract base class implementing the ability to be clicked.
    /// </summary>
    public abstract class ClickableControl : Control
    {
        /// <summary>
        /// Gets or sets if this object generates mouse click events.
        /// </summary>
        public bool GeneratesMouseClicks
        {
            get;
            set;
        }

        /// <summary>
        /// Gets the bounding box used for Clicking
        /// </summary>
        public BoundingBox ClickBox
        {
            get
            {
                Vector2 pos = Position;
                return new BoundingBox(new Vector3(pos.X, pos.Y, 0), new Vector3(pos.X + Width, pos.Y + Height, 0));
            }
        }

        /// <summary>
        /// Gets or sets the tolerance for tap events.
        /// </summary>
        public float TapTolerance
        {
            get;
            set;
        }

        /// <summary>
        /// Called whenever the <see cref="ClickableControl"/> gets clicked.
        /// </summary>
        public event EventHandler Clicked;


        /// <summary>
        /// Constructs a new <see cref="ClickableControl"/> instance.
        /// </summary>
        /// <param name="game"></param>
        protected ClickableControl(Interfaces.ICanHoldComponents game)
            : base(game)
        {
            TapTolerance = 0;
            //GestureHelper.Initialize(game);
            //GestureHelper.AddCallback(GestureType.Tap, TouchCallback);
            MouseHelper.Initialize(game);
            MouseHelper.LeftButton.Up += new EventHandler<MouseHelperEventArgs>(LeftButton_Up);
            GeneratesMouseClicks = true;
        }

        void LeftButton_Up(object sender, MouseHelperEventArgs e)
        {
            if ((Active) && (GeneratesMouseClicks))
            {
                Vector2 position = new Vector2(e.State.X, e.State.Y);
                BoundingBox TouchBB = new BoundingBox(new Vector3(position.X - TapTolerance, position.Y - TapTolerance, 0),
                                                  new Vector3(position.X + TapTolerance, position.Y + TapTolerance, 0));

                if (ClickBox.Intersects(TouchBB))
                {
                    SignalClick();
                }
            }
        }

        private void TouchCallback(GestureSample gs)
        {
            if ((Active)&&(GeneratesMouseClicks))
            {
                Vector2 position = gs.Position;
                BoundingBox TouchBB = new BoundingBox(new Vector3(position.X - TapTolerance, position.Y - TapTolerance, 0),
                                                  new Vector3(position.X + TapTolerance, position.Y + TapTolerance, 0));

                if (ClickBox.Intersects(TouchBB))
                {
                    SignalClick();
                }
            }
        }

        private void SignalClick()
        {
            if (!anyParentIsDisabled())
                if (Clicked != null)
                {
                    Clicked(this, new EventArgs());
                }
        }

        private bool anyParentIsDisabled()
        {
            GameObject obj = this;
            while ((obj!=null)&&(obj.Enabled==true))
                obj = obj.Parent as GameObject;
            return obj != null;
        }
    }
}
